package ar.edu.itba.bundundu;

import java.io.IOException;
import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Date;


import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ar.edu.itba.bundundu.dao.UserDao;
import ar.edu.itba.bundundu.domain.UserIds;

import com.google.code.facebookapi.FacebookParam;
import com.google.gdata.client.calendar.CalendarService;
import com.google.gdata.data.DateTime;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.calendar.CalendarEntry;
import com.google.gdata.data.calendar.CalendarEventEntry;
import com.google.gdata.data.calendar.CalendarFeed;
import com.google.gdata.data.extensions.When;
import com.google.gdata.data.extensions.Where;

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class NewCalendarEventServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {

    doPost(req, resp);
  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    RequestDispatcher dispatcher;
    String next = (String) req.getParameter("prox");
    String error = "";

    if (next == null || next.equals(""))
      dispatcher = getServletContext().getRequestDispatcher(
          "/newcalendarevent.jsp");
    else
      dispatcher = getServletContext().getRequestDispatcher("/events");

    try {
      // pedir el facebook uid
      Facebook facebook = new Facebook(req
          .getParameter(FacebookParam.SESSION_KEY.toString()));
      Long uid = facebook.getUserId();
      req.setAttribute("my_uid", uid);
      // levantar de la base el token para google calendar
      UserIds user = UserDao.getUser(uid);
      String sessionToken = user.getToken();
      // TODO: guardar el token en la session!
      CalendarService service = new CalendarService("exampleCo-exampleApp-1");
      service.setAuthSubToken(sessionToken, null);

      // levantar los calendarios de tipo "owner"
      ArrayList<CalendarEntry> calendars = new ArrayList<CalendarEntry>();
      URL feedUrl = new URL(
          "http://www.google.com/calendar/feeds/default/owncalendars/full");
      CalendarFeed resultFeed = service.getFeed(feedUrl, CalendarFeed.class);
      for (int i = 0; i < resultFeed.getEntries().size(); i++) {
        CalendarEntry entry = resultFeed.getEntries().get(i);
        calendars.add(i, entry);

      }
      req.setAttribute("calendars", calendars);
      if (req.getParameter("is_post") == null) {
        dispatcher.forward(req, resp);

      } else {// levantar los parametros del form y crear el evento
        // Inicializar el calendar
        String calendar = req.getParameter("calendar").toString();
        calendar = calendar
            .substring("http://www.google.com/calendar/feeds/default/calendars/"
                .length());

        URL postUrl = new URL("http://www.google.com/calendar/feeds/"
            + calendar + "/private/full");
        CalendarEventEntry myEntry = new CalendarEventEntry();

        req.setAttribute("needed_url", "http://www.google.com/calendar/feeds/"
            + calendar + "/private/full");

        // input del form
        String title = req.getParameter("title").toString();
        String description = req.getParameter("desc").toString();
        String valueString = req.getParameter("where").toString();
        Where where = new Where(null, null, valueString);
        
        String startDate = req.getParameter("startDate").toString();
        error = error + validateDate(startDate,1);

        String startTime = req.getParameter("startTime").toString();
        error = error + validateTime(startTime,1);
        
        String endDate = req.getParameter("endDate").toString();
        error = error + validateDate(endDate,2);
        
        String endTime = req.getParameter("endTime").toString();
        error = error + validateTime(endTime,2);

        if(!error.equals("")){
          throw new Exception();
        }
        // String tzOffset = req.getParameter("tzOffset").toString();
        String tzOffset = "-03";// TODO: levantarlo del calendar seleccionado

        // inicializacion de variables
        // ////////////////////////////////////myEntry.setId(calendar);

        myEntry.setTitle(new PlainTextConstruct(title));
        myEntry.setContent(new PlainTextConstruct(description));
        DateTime real_startTime = DateTime.parseDateTime(startDate + "T"
            + startTime + ":00" + tzOffset + ":00");
        DateTime real_endTime = DateTime.parseDateTime(endDate + "T" + endTime
            + ":00" + tzOffset + ":00");
        // ("2009-12-13T15:00:00-08:00");

        When eventTimes = new When();
        eventTimes.setStartTime(real_startTime);
        eventTimes.setEndTime(real_endTime);
        myEntry.addTime(eventTimes);
        myEntry.addLocation(where);

        // Send the request and receive the response:
        CalendarEventEntry insertedEntry = service.insert(postUrl, myEntry);
        req.setAttribute("inserted_title", insertedEntry.getTitle()
            .getPlainText().toString());
        
        
        
        //create facebook event
        if(req.getParameter("facebook_event") != null
            && req.getParameter("facebook_event").equals("on")){
          Map<String, String> info = new HashMap<String, String>();
          info.put("name", title);
          info.put("category", "Other");//TODO: hacer select en el form
          info.put("subcategory", "Festival");//TODO: hacer select en el form
          info.put("host", "(not defined)");//TODO
          info.put("location", valueString);
          info.put("city", null);
          info.put("start_time", getSeconds(startDate, startTime));
          info.put("end_time", getSeconds(endDate, endTime));
          info.put("description", description);
          
          
          
          try{
            facebook.getClient().events_create(info);
          }catch(Exception e){
            req.setAttribute("facebook_event_resp", e.getMessage());
          }
        }
            
            
      }
     }catch (Exception e) {
      req.setAttribute("error", error + (e.getMessage()!=null?e.getMessage():""));
    }
    dispatcher.forward(req, resp);
  }

  private String validateTime(String startTime, int num) {
    String error = "";
    String regexp = "[0-9]{2}[:][0-9]{2}";
    Pattern pSD = Pattern.compile(regexp);
    Matcher mSD = pSD.matcher(startTime);
    if (!mSD.find()){
      error="Invalid " + ((num==1)?"start":"end") + " time.<br>";
    }
    return error;
  }

  private String validateDate(String startDate, int num) {
    String error = "";
    String regexp = "[0-9]{4}[-][0-9]{2}[-][0-9]{2}";
    Pattern pSD = Pattern.compile(regexp);
    Matcher mSD = pSD.matcher(startDate);
    if (!mSD.find()){
      error="Invalid " + (num==1?"start":"end") + " date.<br>";
    }
    else{
      
      DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
      try {
        Date date = (Date)formatter.parse(startDate);
      } catch (ParseException e) {
        error="Invalid " + (num==1?"start":"end") + " date.<br>";
      }
    }

    return error;
  }
  
  private String getSeconds(String date, String time){
    DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH:mm");
    Date aux_date = null;
    try{
      aux_date = (Date)formatter.parse(date +"-"+time );
    }catch(Exception e){
      return "";
    }
    Calendar c = Calendar.getInstance();
    c.setTime(aux_date);
    Long respuesta = (c.getTimeInMillis()/1000)+8*60*60;
    return respuesta.toString();
  }
  

}
